<?php

class FriendService extends AbstractService
{
    /**
     * @var FriendService
     */
    private static $instance;

    /**
     * Get the instance of FriendService.
     *
     * @return FriendService
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new FriendService();
        }
        return self::$instance;
    }

    /**
     * Construction.
     */
    protected function __construct()
    {
        parent::__construct();
    }

    /**
     * 处理创建时的逻辑
     *
     * @param int $shardId
     * @return void
     */
    public function handleCreate($shardId)
    {

    }

    /**
     * 处理登录时的逻辑
     * 1. 同步玩家的好友信息
     *
     * @param int $userId
     * @return void
     */
    public function handleLogin($userId)
    {
        $this->clearFriendHandleInfo($userId);
    }

    /**
     * 提供当前 service 数据
     *
     * @param int $userId
     * @param boolean $visitMode default false
     * @return array()
     * )
     */
    public function info($userId, $visitMode = false)
    {
        $reqTime = GameService::get()->getReqTime();
        $requestList = $this->getRequestList($userId, $reqTime);
        $selfRequestList = $this->getSelfRequestList($userId, $reqTime);
        $friendList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);
        $friendCode = $this->getFriendsCode($userId);
        return [
            $requestList,
            $selfRequestList,
            $friendList,
            $friendCode
        ];
    }

    /**
     * 生成好友码
     *
     * @param int $userId
     * @return FriendCodeVo $friendCode
     */
    public function getFriendsCode($userId)
    {
        /** @var FriendCodeVo | null $inviteCode */
        $friendCode = SzPersister::get()->getVo(null, GameConst::ORM_NAME_FRIEND_CODE, $userId);

        if (!$friendCode) {
            // 生成不重复的随机好友码
            $friendCodeTxt = $this->genFriendCode($userId);

            $friendCode = new FriendCodeVo($userId,        // userId
                $friendCodeTxt, // friendCode
                true);

            SzPersister::get()->setVo($friendCode);
        }

        return $friendCode;
    }

    /**
     * 批量请求添加好友
     * @param int $userId
     * @param array $friendCodes
     * @param int $reqTime
     * @return int
     * @throws SzException
     */
    public function multipleRequestFriend($userId, $friendCodes, $reqTime)
    {
        $result = [];
        $friendVoList = $this->getFriendListWithMargeCache($userId);
        foreach ($friendCodes as $friendCode) {
            $result[$friendCode] = $this->requestFriend($userId, $friendCodes, $reqTime, $friendVoList);
        }
        return $result;
    }

    /**
     * 请求添加好友
     * @param $userId
     * @param $friendCode
     * @param $reqTime
     * @param $friendVoList
     * @return int
     * @throws SzException
     */
    public function requestFriend($userId, $friendCode, $reqTime, $friendVoList = null)
    {
        $friendId = $this->searchFriendWithCode($friendCode);
        if (!$friendId) {
            throw new SzException(29101, $friendCode);
        }
        if ($userId == $friendId) {
            return GameConst::FRIEND_NO_SELF;
        }
        /**
         * @var $friendVoList NewFriendsVoList
         */
        if (is_null($friendVoList)) {
            $friendVoList = $this->getFriendListWithMargeCache($userId);
        }
        if ($friendVoList->getElement($friendId, false)) {
            return GameConst::ADD_FRIEND_FAILED_IS_FRIEND;
        }
        //TODO 判断是否已到上限（未知策划）
        //CACHE_KEY_FRIENDS_ADD_FRIEND 为请求列表
        GameService::get()->lock(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId);
        SzCacheFactory::get()->getAppCache()->hSet(GameConst::CACHE_KEY_FRIENDS_SELF_REQUESTS . $userId, $friendId, $reqTime);
        SzCacheFactory::get()->getAppCache()->hSet(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $friendId, $userId, $reqTime);
        GameService::get()->unlock(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId);


        // 记录日志：申请添加好友
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:friends|action:apply|',
                'item' => $friendId,
                'value' => 1,
            )
        ));
        return GameConst::ADD_FRIEND_SUCCESS;
    }

    /**
     * 同意添加
     * @param $userId
     * @param $friendId
     * @return int
     */
    public function confirmAdd($userId, $friendId)
    {
        if ($userId == $friendId) {
            return GameConst::FRIEND_NO_SELF;
        }
        GameService::get()->lock(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId);
        $requestInfo = SzCacheFactory::get()->getAppCache()->hGet(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId, $friendId);
        if (!$requestInfo) {
            GameService::get()->unlock(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId);
            return GameConst::CONFIRM_FAILED_NO_FRIEND_REQUEST;
        }
        /**
         * @var $friendVoList NewFriendsVoList
         * @var $friendVo NewFriendsVo
         */
        $friendVoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);
        if ($friendVoList->getElement($friendId, false)) {
            GameService::get()->unlock(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId);
            SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_SELF_REQUESTS . $friendId, $userId);
            SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId, $friendId);
            return GameConst::ADD_FRIEND_FAILED_IS_FRIEND;
        }
        $friendVo = new NewFriendsVo($userId, $friendId, 1, -1, 0,0,0,0,0,true);
        $friendVoList->addElement($friendVo);
        $friendVoList->setElement($friendId, $friendVo);
        SzPersister::get()->setVoList($friendVoList);
        SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_SELF_REQUESTS . $friendId, $userId);
        SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId, $friendId);
        SzCacheFactory::get()->getAppCache()->hSet(GameConst::CACHE_KEY_FRIENDS_CONFIRM . $friendId, $userId, -1);
        GameService::get()->unlock(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId);


        // 记录日志：接受好友添加申请
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:friends|action:accept|',
                'item' => $friendId,
                'value' => 1,
            )
        ));
        return GameConst::ADD_FRIEND_SUCCESS;
    }

    /**
     * 给申请加好友的玩家添加好友，给被申请人添加缓存
     * @param $userId
     * @param $friendId
     * @param $inviteId
     * @return bool
     * @throws SzException
     */
    public function addFriend($userId, $friendId, $inviteId)
    {
        if ($userId == $friendId) {
            return false;
        }
        /**
         * @var $friendVoList NewFriendsVoList
         * @var $userFriendVoList NewFriendsVoList
         * @var $friendVo NewFriendsVo
         * @var $userFriendVo NewFriendsVo
         */
        $friendVoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);

        $upper_limit_of_friends = SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'upper_limit_of_friends', true);
        if ($upper_limit_of_friends['value'] <= count($friendVoList->getList())) {
            return false;
        }

        $userFriendVoList = SzPersister::get()->getVoList($friendId, GameConst::ORM_NAME_NEW_FRIEND);
        if ($upper_limit_of_friends['value'] <= count($userFriendVoList->getList())) {
            return false;
        }

        if ($friendVoList->getElement($friendId, false) || $userFriendVoList->getElement($userId,false)) {
            return false;
        }
        $friendVo = new NewFriendsVo($userId, $friendId, 1, -1, 0, 0,0,0,0,true);
        $friendVoList->addElement($friendVo);
        $friendVoList->setElement($friendId, $friendVo);
        SzPersister::get()->setVoList($friendVoList);
        $userFriendVo = new NewFriendsVo($friendId, $userId, 1, $inviteId, 0, 0,0,0,0,true);
        $userFriendVoList->addElement($userFriendVo);
        $userFriendVoList->setElement($userId,$userFriendVo);
        SzPersister::get()->setVoList($userFriendVoList);

        $inviteSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_INVITE, null, true);
        if (isset($inviteSettings[$inviteId])) {

            /**
             * @var $inviteCountInfo ModuleProfileInfoVo
             * @var $inviteNumInfo ModuleProfileInfoVo
             */
            $profileInfoList = SzPersister::get()->getVoList($friendId, ModuleProfileConst::ORM_NAME_PROFILE_INFO);
            $inviteNumInfo = $profileInfoList->getElement(GameConst::USER_INFO_TYPE_INVITE_NUM,false);
            if (!$inviteNumInfo) {
                $inviteCount = 0;
                foreach ($userFriendVoList->getList() as $friendVo) {
                    if ($friendVo->getInviteId() != -1 && $inviteSettings[$friendVo->getInviteId()]) {
                        $inviteCount++;
                    }
                }
                NewFriendService::get()->getInviteNum($friendId,$inviteCount,$profileInfoList,$inviteNumInfo);

            } else {
                $inviteCount = $inviteNumInfo->getRawInfo();
                $inviteCount++;
                $inviteNumInfo->setInfo((int)$inviteCount);
                $profileInfoList->updateElement(GameConst::USER_INFO_TYPE_INVITE_NUM, $inviteNumInfo);
                SzPersister::get()->setVoList($profileInfoList);
            }

        }
        return true;
    }

    /**
     * 申请人取消申请
     * @param $userId  int 申请人Id
     * @param $friendId int 被申请人Id
     * @return  int
     */
    public function cancelRequest($userId, $friendId)
    {
        GameService::get()->lock(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId);
        //自己的申请列表
        SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_SELF_REQUESTS . $userId, $friendId);
        //好友的申请列表
        SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $friendId, $userId);
        GameService::get()->unlock(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId);
        return GameConst::CANCEL_REQUEST_SUCCESS;
    }

    /**
     * 被申请人拒绝申请
     * @param $userId int 被申请人Id
     * @param $friendId int 申请人Id（被拒绝的玩家）
     * @return int
     */
    public function denyRequest($userId, $friendId)
    {
        //被拒绝人的申请列表
        SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_SELF_REQUESTS . $friendId, $userId);
        //自己的申请列表
        SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId, $friendId);

        // 记录日志：拒绝添加好友申请
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:friends|action:reject|',
                'item' => $friendId,
                'value' => 1,
            )
        ));
        return GameConst::CANCEL_REQUEST_SUCCESS;
    }

    /**
     * 删除好友
     * @param $userId
     * @param $friendId
     * @return int
     */
    public function removeFriend($userId, $friendId)
    {
        $friendVoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);
        if (!$friendVoList->getElement($friendId, false)) {
            return GameConst::DELETE_FRIEND_FAILED_NO_FRIEND;
        }
        //删除好友
        $friendVoList->deleteElement($friendId);
        SzPersister::get()->setVoList($friendVoList);
        SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_CONFIRM . $userId, $friendId);

        // 记录日志：删除好友
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:friends|action:delete|',
                'item' => $friendId,
                'value' => 1,
            )
        ));
        return GameConst::DELETE_FRIEND_SUCCESS;
    }

    /**
     * 删除过期的申请
     * @param $userId
     * @param $reqTime
     */
    public function clearTimeOutRequests($userId, $reqTime)
    {
        //自己的被申请记录
        $requestList = SzCacheFactory::get()->getAppCache()->hGetAll(GameConst::CACHE_KEY_FRIENDS_SELF_REQUESTS . $userId);
        foreach ($requestList as $friendId => $time) {
            if ($reqTime >= $time + SzTime::HOURS24 * 30) {
                SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $friendId, $userId);
                SzCacheFactory::get()->getAppCache()->hDel(GameConst::CACHE_KEY_FRIENDS_SELF_REQUESTS . $userId, $friendId);
            }
        }
    }

    /**
     * 更新操作日志
     * @param $friendId
     * @param $friendList
     * @param $friendInfo
     * @throws SzException
     */
    public function updateFriendHandleInfo($friendId, $friendList, $friendInfo)
    {
        $reqTime = GameService::get()->getReqTime();
        /**
         * @var $friendList NewFriendsVoList
         * @var $friendInfo NewFriendsVo
         */

        if(SzTime::getDate($friendInfo->getStealTime()) != SzTime::getDate($reqTime)) {
            $friendInfo->setStealNum(0);
            $friendInfo->setStealTime($reqTime);
        }

        $friendInfo->updateStealNum(1);
        $friendList->updateElement($friendId,$friendInfo);
        SzPersister::get()->setVoList($friendList);
        return;
    }

    /**
     * 获取好友家操作记录
     * @param $userId
     * @param $friendId
     * @param array $totalCount
     * @return int|mixed
     * @throws SzException
     */
    public function getFriendHandleInfo($userId, $friendId, $totalCount)
    {
        $reqTime = GameService::get()->getReqTime();
        /**
         * @var $friendList NewFriendsVoList
         * @var $friendInfo NewFriendsVo
         */
        $friendList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);
        $friendInfo = $friendList->getElement($friendId,false);
        if (!$friendInfo) {
            return $totalCount['value'];
        }

        if(SzTime::getDate($friendInfo->getStealTime()) != SzTime::getDate($reqTime)) {
            return 0;
        }

        return $friendInfo->getStealNum();
    }

    // 每日清除记录
    public function clearFriendHandleInfo($userId)
    {
        if (GameService::get()->isDailyFirstLogin($userId) == false) {
            return;
        }
        UserService::get()->updateProfileInfo($userId, GameConst::USER_INFO_TYPE_DAILY_FRIEND_HANDLE_TIMES, []);
    }

    /**
     * 获取当前玩家的被申请列表
     * @param $userId
     * @param $reqTime
     * @return array
     */
    public function getRequestList($userId, $reqTime)
    {
        $this->clearTimeOutRequests($userId, $reqTime);
        $requestList = SzCacheFactory::get()->getAppCache()->hGetAll(GameConst::CACHE_KEY_FRIENDS_ADD_FRIEND . $userId);
        return $requestList;
    }

    /**
     * 获取自己的申请列表
     * @param $userId
     * @param $reqTime
     * @return array
     */
    public function getSelfRequestList($userId, $reqTime)
    {
        $this->clearTimeOutRequests($userId, $reqTime);
        $selfRequestList = SzCacheFactory::get()->getAppCache()->hGetAll(GameConst::CACHE_KEY_FRIENDS_SELF_REQUESTS . $userId);
        return $selfRequestList;
    }

    /**
     * 获取好友列表
     * @param $userId
     * @param $isSelf
     * @return NewFriendsVoList
     */
    public function getFriendListWithMargeCache($userId, $isSelf = false)
    {
        /**
         * @var $friendVoList NewFriendsVoList
         */
        $friendVoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);
        $friendsCache = SzCacheFactory::get()->getAppCache()->hGetAll(GameConst::CACHE_KEY_FRIENDS_CONFIRM . $userId);
        foreach ($friendsCache as $friendId => $inviteId) {
            if ($userId == $friendId) {
                continue;
            }
            if ($friendVoList->getElement($friendId, false)) {
                continue;
            }
            $friendVo = new NewFriendsVo($userId, $friendId, 1, $inviteId, 0, 0,0,0,0,true);
            $friendVoList->addElement($friendVo);
            $friendVoList->setElement($friendId, $friendVo);
        }
        if ($isSelf) {
            SzPersister::get()->setVoList($friendVoList);
            SzCacheFactory::get()->getAppCache()->delete(GameConst::CACHE_KEY_FRIENDS_CONFIRM . $userId);
        }
        return $friendVoList;
    }

    //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
    //-* private function
    //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
    /**
     * 生成好友码
     *
     * @param int $userId
     * @return string
     */
    private function genFriendCode($userId)
    {
        //纯数字7位
//        $code = 999999 + $userId;
        //微信策划要求code=userId，sns要改为1000000起
        $code = $userId;
        // 确认数据库中不重复
        $result = $this->searchFriendWithCode($code);

        // 查到重复好友码，重新生成好友码
        if ($result) {
            return $this->genFriendCode($userId);
        }

        return $code;
    }

    /**
     * 通过好友码获得 userId
     *
     * @param string $friendCode
     * @return int | false $result
     */
    public function searchFriendWithCode($friendCode)
    {
        $result = $this->context->getDb()->select("SELECT `userId` FROM `ft_friend_code` WHERE `friendCode` = '{$friendCode}'");

        if (!empty($result)) {
            return $result[0]['userId'];
        }

        return false;
    }

    /**
     * 获取好友信息列表
     * @param $userId
     * @return array
     */
    public function getFriendInfoList($userId)
    {
        $friendVoList = $this->getFriendListWithMargeCache($userId, true);
        $friendInfoList = [];
        /**
         * @var $friendVo NewFriendsVo
         */
        foreach ($friendVoList->getList() as $friendId => $friendVo) {
            $friendInfoList[$friendId] = $this->getUserSocialInfo($friendId, $friendVo->getIsNew(), $friendVo->getInviteId(), $friendVo->getIsGetInviteReward());
        }
        return $friendInfoList;
    }

    /**
     * 获取被申请列表
     * @param $userId
     * @param $reqTime
     * @return array
     */
    public function getRequestInfoList($userId, $reqTime)
    {
        $requestList = $this->getRequestList($userId, $reqTime);
        $requestInfoList = [];
        foreach ($requestList as $friendId => $time) {
            $requestInfoList[$friendId] = $this->getUserSocialInfo($friendId);
        }
        return $requestInfoList;
    }

    /**
     * 获取玩家社交相关信息（头像、花镇名称、玩家等级）
     *
     * @param int $userId
     * @param int $isNew
     * @param int $inviteId
     * @param int $isGetInviteReward
     * @return array
     * <pre>
     * array(
     *      'userId' => $userId
     *      'userLevel' => $userLevel
     *      'townName' => $townName
     *      'headImgId' => $headImgId
     *      'isNew' => $isNew
     *      'inviteId' => $inviteId,
     *      'isGetInviteReward' => $isGetInviteReward
     * )
     * </pre>
     */
    public function getUserSocialInfo($userId, $isNew = 1, $inviteId = -1, $isGetInviteReward = 0)
    {
        $profileInfoList = SzPersister::get()->getVoList($userId, ModuleProfileConst::ORM_NAME_PROFILE_INFO);

        $res = array(
            'userId' => $userId,
            'userLevel' => UserService::get()->getUserLevel($userId),
            'townName' => UserService::get()->getTownName($userId, $profileInfoList),
            'headImgId' => UserService::get()->getHeadIcon($userId, $profileInfoList),
            'isNew' => $isNew,
            'inviteId' => $inviteId,
            'isGetInviteReward' => $isGetInviteReward
        );

        //获取玩家的头像框数据
        $profileInfo = $profileInfoList->getElement(GameConst::USER_INFO_TYPE_HEAD_FRAME,false);
        if (!$profileInfo){
            $res['headFrame'] = 0;
        }
        else{
            $res['headFrame'] = $profileInfo->getInfo();
        }

        return $res;
    }

    /**
     * 领取单个邀请奖励
     * @param $userId
     * @param $friendId
     * @throws SzException
     * @return bool
     */
    public function getInviteFriendReward($userId, $friendId)
    {
        /**
         * @var $friendVoList NewFriendsVoList
         * @var $friendVo NewFriendsVo
         */
        $friendVoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);
        $friendVo = $friendVoList->getElement($friendId, false);
        if (!$friendVo) {
            throw new SzException(29102, $friendId);
        }
        if ($friendVo->getInviteId() == -1) {
            throw new SzException(29104, $friendId);
        }
        if ($friendVo->getIsGetInviteReward()) {
            throw new SzException(29103, $friendId);
        }
        $inviteSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_INVITE, $friendVo->getInviteId(), true);
        $tid = '';
        foreach ($inviteSetting['award'] as $entityId => $cont) {
            GameService::get()->handleEntity($userId, $entityId, $cont, true);
            $tid .= $entityId.':'.$cont.'|';
        }

        // 数据采集:分享
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:invite|action:success|',
                'item' => $friendVo->getFriendId(),
                'value' => 1
            )
        ));

        // 数据采集:产出
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_OUTPUT, array(
            'clientData' => array(
                'tid' => $tid,
                'item' => 'invite_success&'.$friendVo->getFriendId(),
            )
        ));

        $friendVo->setIsGetInviteReward(1);
        $friendVoList->updateElement($friendId, $friendVo);
        SzPersister::get()->setVoList($friendVoList);
        return true;
    }

    /**
     * 获取邀请个数阶段奖
     * @param $userId
     * @param $count
     * @throws SzException
     * @return bool
     */
    public function getInviteFriendCountReward($userId, $count)
    {
        $inviteRewardSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_INVITE_REWARD, $count, true);
        /**
         * @var $friendVoList NewFriendsVoList
         * @var $friendVo NewFriendsVo
         */
        $friendVoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);
        $gotRewards = UserService::get()->getInfo($userId, GameConst::USER_INFO_TYPE_INVITE_COUNT);
        $gotRewards = $gotRewards ? $gotRewards : [];
        $inviteCount = 0;
        if (in_array($count, $gotRewards)) {
            throw new SzException(29106, $count);
        }
        $inviteSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_INVITE, null, true);
        foreach ($friendVoList->getList() as $friendId => $friendVo) {
          
            if ($friendVo->getInviteId() != -1 && $inviteSettings[$friendVo->getInviteId()]) {
                $inviteCount++;
            }
        }
        $inviteCount = NewFriendService::get()->getInviteNum($userId,$inviteCount);
        if ($inviteRewardSettings['number'] > $inviteCount) {
            throw new SzException(29105, [$inviteCount, $count]);
        }
        $tid = '';
        foreach ($inviteRewardSettings['award'] as $entityId => $num) {
            GameService::get()->handleEntity($userId, $entityId, $num, true);
            $tid .= $entityId.':'.$count.'|';
        }
        $gotRewards[] = $count;
        UserService::get()->updateProfileInfo($userId, GameConst::USER_INFO_TYPE_INVITE_COUNT, $gotRewards);


        // 数据采集:分享
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:invite|action:achieve|',
                'item' => $inviteCount,
                'value' => 1
            )
        ));

        // 数据采集:产出
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_OUTPUT, array(
            'clientData' => array(
                'tid' => $tid,
                'item' => 'invite_achieve&'.$inviteCount,
            )
        ));

        return true;
    }

    /**
     * 获取好友推荐列表
     * @param $userId
     * @return array
     */
    public function getFriendRecommendList($userId)
    {
        $listCount = 10;
        // 数据库的分库中随机取出一个shareId，然后
        $serversConfig = SzConfig::get()->loadAppConfig('database', 'MySql');
        $shardId = mt_rand(0, count($serversConfig) - 1);

        $instance = new SzMySqlDb($serversConfig[$shardId]);

        $moduleProfiles = $instance->select("SELECT `userId`, `level` FROM `module_profile` WHERE `userId` != {$userId} ORDER BY `lastLoginTime` DESC limit " . ($listCount * 100));
        shuffle($moduleProfiles);

        $result = [];

        $friendVoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);

        $reqTime = GameService::get()->getReqTime();
        $requestList = $this->getRequestList($userId, $reqTime);
        foreach ($moduleProfiles as $profile) {
            $friendUserId = $profile['userId'];
            if (in_array($friendUserId, $requestList)) {
                continue;
            }
            $friendVo = $friendVoList->getElement($friendUserId, false);
            if ($friendVo) {
                continue;
            }
            /** @var FriendCodeVo $friendCode */
            $friendCode = SzPersister::get()->getVo(null, GameConst::ORM_NAME_FRIEND_CODE, $userId);
            if (!$friendCode) {
                continue;
            }
            $friendInfo = $this->getUserSocialInfo($friendUserId);
            $friendInfo['friendCode'] = $friendCode->getFriendCode();

            $result[$friendUserId] = $friendInfo;
            if (count($result) >= $listCount) {
                break;
            }
        }
        return $result;
    }

    /**
     * @param $userId
     * @return bool
     * @throws SzException
     */
    public function handleDelFriend($userId) {
        /**
         * @var $friendVoList NewFriendsVoList
         * @var $friendVo NewFriendsVo
         */
        $friendVoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_FRIEND);
        $inviteSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_INVITE, null, true);
        foreach ($friendVoList->getList() as $friendId => $friendVo) {
            if (!$inviteSettings[$friendVo->getInviteId()]) {
                $friendVoList->deleteElement($friendVo->getFriendId());
            }
        }
        SzPersister::get()->setVoList($friendVoList);
        return true;
    }
}